home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / libs / mkfifo / nmp_thread.c < prev    next >
C/C++ Source or Header  |  1997-08-22  |  4KB  |  154 lines

  1. /*
  2. ** ****************************************************************************
  3. ** Thread for exchanging the data. This routine is started by the server in
  4. ** new thread for every nmaed pipe.
  5. ** (c) Klaus Gebhardt, 1997
  6. ** ****************************************************************************
  7. */
  8.  
  9. /*
  10. ** ****************************************************************************
  11. ** This is part of the server the mkfifo command connects to. This program
  12. ** creates a named pipe which is used for communication between the mkfifo
  13. ** routine and the server. The mkfifo sends the name of the named pipe,
  14. ** which should be created and then receives the return code.
  15. ** (c) Klaus Gebhardt, 1997
  16. ** ****************************************************************************
  17. */
  18.  
  19. /*
  20. ** ****************************************************************************
  21. ** This was written for the OS/2 port of Octave, but it is not part of Octave!
  22. ** You can use the code UNMODIFIED. If you think changes are necessary,
  23. ** please send me a mail (gebhardt@crunch.ikp.physik.th-darmstadt.de).
  24. ** Thanks,
  25. **   Klaus Gebhardt
  26. ** ****************************************************************************
  27. */
  28.  
  29. #include "nmp.h"
  30.  
  31. /*
  32. ** This function creates a named pipe and connects to it. The function
  33. ** returns 0 on success, -1 on error.
  34. */
  35. static int create_npipe (const char *name, HPIPE *hpipe)
  36. {
  37.   APIRET apiret;
  38.  
  39.   apiret = DosCreateNPipe (name, hpipe, NP_ACCESS_DUPLEX,
  40.                            NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE |
  41.                            0xFF, 1024L, 1024L, -1);
  42.  
  43.   if (apiret)  return -1;
  44.  
  45.   apiret = DosConnectNPipe (*hpipe);
  46.   if (apiret && (apiret != 233))  return -1;
  47.  
  48.   apiret = DosSetNPHState (*hpipe, NP_WAIT);
  49.   if (apiret && (apiret != 233))  return -1;
  50.  
  51.   return 0;
  52. }
  53.  
  54.  
  55. /*
  56. ** This routine disconnects from a named pipe and closes the named pipe.
  57. ** It returns 0 on success, -1 on error.
  58. */
  59. static int disconnect_npipe (HPIPE hpipe)
  60. {
  61.   DosDisConnectNPipe (hpipe);
  62.   DosClose (hpipe);
  63.   return 0;
  64. }
  65.  
  66.  
  67. /*
  68. ** This is the thread for moving the data from one end to the other. When
  69. ** a client closes its connection to a named pipe, the named pipe will be
  70. ** closed and recreated.
  71. */
  72. void nmp_thread (void *ptr)
  73. {
  74.   APIRET apiret;
  75.   HPIPE  hpipe1, hpipe2;
  76.   ULONG  count1r = 0, count2w = 0, count2r = 0, count1w = 0, tmp;
  77.   AVAILDATA available1, available2;
  78.   ULONG  state1, state2;
  79.  
  80.   _named_pipe_ *nmp;
  81.   char data1[1024], data2[1024];
  82.   int rc;
  83.  
  84.   nmp = (_named_pipe_ *) ptr;
  85.   nmp->result = 0;
  86.  
  87.   rc = create_npipe (nmp->name, &hpipe1);  if (rc)  nmp->result = -1;
  88.   rc = create_npipe (nmp->name, &hpipe2);  if (rc)  nmp->result = -1;
  89.  
  90.   DosPostEventSem (_hev_);
  91.  
  92.   while (nmp->tid != -1)
  93.     {
  94.       DosPeekNPipe (hpipe1, &rc, sizeof(rc), &tmp, &available1, &state1);
  95.       DosPeekNPipe (hpipe2, &rc, sizeof(rc), &tmp, &available2, &state2);
  96.  
  97.       if ((count1r > count2w) || (available1.cbpipe > 0))
  98.         {
  99.       if (count1r <= count2w)
  100.         {
  101.           DosRead (hpipe1, data1, sizeof(data1), &count1r);
  102.           count2w = 0;
  103.         }
  104.  
  105.       if (count1r > count2w)
  106.         {
  107.           DosWrite (hpipe2, data1+count2w, count1r-count2w, &tmp);
  108.           count2w += tmp;
  109.         }
  110.     }
  111.       else if (state1 == NP_STATE_CLOSING)
  112.         {
  113.       disconnect_npipe (hpipe1);
  114.       rc = create_npipe (nmp->name, &hpipe1);
  115.       if (rc)  goto error;
  116.         }
  117.  
  118.  
  119.       if ((count2r > count1w) || (available2.cbpipe > 0))
  120.         {
  121.       if (count2r <= count1w)
  122.         {
  123.           DosRead (hpipe2, data2, sizeof(data2), &count2r);
  124.           count1w = 0;
  125.         }
  126.  
  127.       if (count2r > count1w)
  128.         {
  129.           DosWrite (hpipe1, data2+count1w, count2r-count1w, &tmp);
  130.           count1w += tmp;
  131.         }
  132.     }
  133.       else if (state2 == NP_STATE_CLOSING)
  134.         {
  135.       disconnect_npipe (hpipe2);
  136.       rc = create_npipe (nmp->name, &hpipe2);
  137.       if (rc)  goto error;
  138.         }
  139.     }
  140.  
  141.  
  142.   disconnect_npipe (hpipe1);
  143.   disconnect_npipe (hpipe2);
  144.   _endthread ();
  145.   return;
  146.  
  147. error:
  148.   nmp->result = -1;
  149.   disconnect_npipe (hpipe1);
  150.   disconnect_npipe (hpipe2);
  151.   _endthread ();
  152.   return;
  153. }
  154.